package com.example.parent.bookmanage_ehcache.service.impl;

import com.example.parent.bookmanage_ehcache.dao.BookRepository;
import com.example.parent.bookmanage_ehcache.entity.Book;
import com.example.parent.bookmanage_ehcache.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 图书服务实现类（集成Ehcache缓存）
 * 实现BookService接口定义的业务逻辑，通过Ehcache本地缓存提升数据访问性能
 * 负责图书的查询、更新和删除操作，并维护缓存与数据库的一致性
 */
@Service // 标识为服务层组件，由Spring容器管理
@CacheConfig(cacheNames = "book") // 缓存配置，指定默认缓存名称为"book"，统一管理缓存命名空间
@Transactional // 开启事务管理，确保数据库操作的原子性（如更新、删除操作的事务一致性）
public class BookServiceImpl implements BookService {

    /**
     * 注入图书数据访问接口
     * 用于与数据库交互，执行CRUD操作，实现业务逻辑与数据访问层的解耦
     */
    @Autowired
    private BookRepository bookRepository;

    /**
     * 根据图书ID查询图书信息
     * 优先从Ehcache缓存获取数据，缓存未命中时查询数据库并将结果存入缓存
     *
     * @param id 图书唯一标识ID
     * @return Book 图书实体对象（包含ID、名称、作者等信息）
     */
    @Cacheable(key = "#id") // 缓存注解：以图书ID为键，将查询结果存入缓存
    @Override
    public Book findById(Integer id) {
        // 当缓存未命中时执行此方法（查询数据库），并打印日志标识
        System.out.println("从数据库查询图书，id=" + id);
        // 从数据库查询图书（实际应用中需处理Optional可能为空的情况）
        return bookRepository.findById(id).get();
    }

    /**
     * 根据图书ID修改图书名称
     * 更新数据库后同步更新Ehcache缓存，确保缓存与数据库数据一致
     *
     * @param id   图书唯一标识ID
     * @param name 新的图书名称
     * @return Book 修改后的图书实体对象（将被更新到缓存）
     */
    @CachePut(key = "#id") // 缓存更新注解：更新数据库后，将结果同步到缓存
    @Override
    public Book updateById(Integer id, String name) {
        // 先查询获取原图书信息（优先从缓存获取）
        Book book = this.findById(id);
        // 更新图书名称
        book.setName(name);
        // 保存更新到数据库并返回更新后的对象（该对象将覆盖缓存中对应键的值）
        return bookRepository.save(book);
    }

    /**
     * 根据图书ID删除图书
     * 删除数据库记录的同时清除Ehcache中对应的缓存，避免缓存脏数据
     *
     * @param id 图书唯一标识ID
     */
    @CacheEvict(key = "#id") // 缓存清除注解：删除数据库记录后，清除缓存中对应键的数据
    @Override
    public void deleteById(Integer id) {
        // 从数据库删除指定ID的图书
        bookRepository.deleteById(id);
    }
}